﻿/*----------------------------------------------------------------
// 公司名称：公司名称
// 
// 产品名称：Gaf
//
// 创 建 人：netcasewqs
// 创建日期：2022/3/4
// 邮    箱：netcasewqs@qq.com
//
// Copyright (C) 2022 Gaf，保留所有权利。
//
//----------------------------------------------------------------*/
namespace Gaf.Impl;

record LiteActivatorDescriptor : ActivatorDescriptor
{
    public object? Attribute { get; private set; }
    public MethodInfo? GetNameMethod { get; private set; }
    public MethodInfo? GetStartLevelMethod { get; private set; }


    private const string _Name = nameof(IAddinDescriptor.Name);
    private const string _StartLevel = nameof(IAddinDescriptor.StartLevel);

    private const string get_Name = nameof(get_Name);
    private const string get_StartLevel = nameof(get_StartLevel);

    private void Copy(ActivatorDescriptor from)
    {
        Constructor = from.Constructor;
        Start = from.Start;
        Configure = from.Configure;
        Match = from.Match;
        Stop = from.Stop;
        SetAssembliesMethod = from.SetAssembliesMethod;
    }

    static (MethodInfo? get_Name_method, MethodInfo? get_StartLevel_method) GetNameAndStartLevelMethods(Type t)
    {
        //name property 
        var methods = t.GetMethods(_flags);
        var get_Name_method = methods.FirstOrDefault(method => method.Name == get_Name && method.ReturnType == typeof(string) && method.GetParameters().Length == 0);
        var get_StartLevel_method = methods.FirstOrDefault(method => method.Name == get_StartLevel && AddinActivator.IsAddinStateType(method.ReturnType) && method.GetParameters().Length == 0);

        return (get_Name_method, get_StartLevel_method);
    }

    const BindingFlags _flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
    public static LiteActivatorDescriptor? ParseLiteActivatorDescriptor(Type t)
    {
        var descriptor = ParseActivatorDescriptor(t);
        if (descriptor == null) return null;

        var result = new LiteActivatorDescriptor();
        result.Copy(descriptor);

        //get_Name method
        var nameAndStartLevelMethods = GetNameAndStartLevelMethods(t);
        result.GetNameMethod = nameAndStartLevelMethods.get_Name_method;
        result.GetStartLevelMethod = nameAndStartLevelMethods.get_StartLevel_method;

        if (result.GetNameMethod == null)
        {
            //从Attribute 注解中获取Name 和StartLevel 属性
            var items = (from attribute in t.GetCustomAttributes()
                         let nameAndStartLevel = GetNameAndStartLevelMethods(attribute.GetType())
                         where nameAndStartLevel.get_Name_method != null
                         select (
                            nameAndStartLevel.get_Name_method,
                            nameAndStartLevel.get_StartLevel_method,
                            nameAndStartLevel.get_StartLevel_method != null ? 2 : 1,
                            attribute as Attribute)).OrderByDescending(p => p.Item3).ToList();

            foreach (var (get_Name_method, get_StartLevel_method, length, att) in items)
            {
                if (length == 2)
                {
                    result.GetNameMethod = get_Name_method;
                    result.GetStartLevelMethod = get_StartLevel_method;
                    result.Attribute = att;
                }
                else if (length == 1)
                {
                    result.GetNameMethod = get_Name_method;
                    result.Attribute = att;
                }
            }
        }


        if (result.GetNameMethod == null) return null;

        return result;
    }


}

